﻿using AutoMapper;
using Microsoft.EntityFrameworkCore;
using Order.Api.Read.Application.Command;
using Order.Api.Read.Dto.Order;
using Order.Domain.Enum;
using Order.Domain.OrderDomain;
using Order.ErrorCode;
using Order.Interstructrue;
using System;
using System.Linq;
using System.Threading.Tasks;
using System.ComponentModel;
using System.Reflection;

namespace Order.Api.Read.Service.RegistrationOrderService
{
    /// <summary>
    /// 挂号订单服务实现
    /// </summary>
    public class RegistrationOrderService : IRegistrationOrderService
    {
        private readonly MedicalDbContext _context;
        private readonly IMapper _mapper;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="context">数据库上下文</param>
        /// <param name="mapper">AutoMapper</param>
        public RegistrationOrderService(MedicalDbContext context, IMapper mapper)
        {
            _context = context ?? throw new ArgumentNullException(nameof(context));
            _mapper = mapper ?? throw new ArgumentNullException(nameof(mapper));
        }

        /// <summary>
        /// 获取挂号订单分页数据
        /// </summary>
        /// <param name="command">分页查询命令</param>
        /// <returns>分页结果</returns>
        public async Task<ApiPageIng<RegistrationOrderPageDto>> GetRegistrationOrderPageAsync(RegistrationOrderPageCommand command)
        {
            try
            {
                var query = command.Query;

                // 构建基础查询
                var baseQuery = from order in _context.RegistrationOrder
                                join patient in _context.Patient on order.PatientId equals patient.Id into patientGroup
                                from patient in patientGroup.DefaultIfEmpty()
                                join registration in _context.Registration on order.Id equals registration.RegistrationOrderId into registrationGroup
                                from registration in registrationGroup.DefaultIfEmpty()
                                where !order.IsDeleted
                                select new RegistrationOrderPageDto
                                {
                                    Id = order.Id,
                                    OrderNo = order.OrderNo,
                                    CreateTime = order.CreateTime,
                                    PatientName = patient.PatientName,
                                    PatientPhone = patient.Phone,
                                    DoctorName = registration.Doctor,
                                    Department = registration.Department,
                                    DepartmentName = registration.Department.HasValue ?
                                        GetEnumDescription(registration.Department.Value) : null,
                                    Amount = order.Amount,
                                    OrderStatus = order.OrderStatus,
                                    OrderStatusName = order.OrderStatus.HasValue ?
                                        GetEnumDescription(order.OrderStatus.Value) : null,
                                    PatientId = order.PatientId,
                                    RegistrationId = registration.Id
                                };

                // 应用关键字搜索
                if (!string.IsNullOrWhiteSpace(query.Keyword))
                {
                    baseQuery = baseQuery.Where(x =>
                        (x.OrderNo != null && x.OrderNo.Contains(query.Keyword)) ||
                        (x.PatientName != null && x.PatientName.Contains(query.Keyword)) ||
                        (x.PatientPhone != null && x.PatientPhone.Contains(query.Keyword)));
                }

                // 应用时间范围筛选
                if (query.StartTime.HasValue)
                {
                    baseQuery = baseQuery.Where(x => x.CreateTime >= query.StartTime.Value);
                }

                if (query.EndTime.HasValue)
                {
                    baseQuery = baseQuery.Where(x => x.CreateTime <= query.EndTime.Value);
                }

                // 应用订单状态筛选
                if (query.OrderStatus.HasValue)
                {
                    baseQuery = baseQuery.Where(x => x.OrderStatus == query.OrderStatus.Value);
                }

                // 按创建时间倒序排列
                baseQuery = baseQuery.OrderByDescending(x => x.CreateTime);

                // 获取总数
                var totalCount = await baseQuery.CountAsync();

                // 分页
                var items = await baseQuery
                    .Skip((query.PageIndex - 1) * query.PageSize)
                    .Take(query.PageSize)
                    .ToListAsync();

                // 构建分页结果
                var result = new ApiPageIng<RegistrationOrderPageDto>
                {
                    Data = items,
                    TotalCount = totalCount,
                    PageIndex = query.PageIndex,
                    PageSize = query.PageSize,
                    TotalPages = (int)Math.Ceiling((double)totalCount / query.PageSize)
                };

                return result;
                return result;
            }
            catch (Exception ex)
            {
                throw new Exception($"获取挂号订单分页数据时发生错误: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// 获取挂号订单详情
        /// </summary>
        /// <param name="command">详情查询命令</param>
        /// <returns>订单详情</returns>
        public async Task<RegistrationOrderDetailDto> GetRegistrationOrderDetailAsync(RegistrationOrderDetailCommand command)
        {
            try
            {
                var orderId = command.Id;

                // 查询挂号订单详情
                var orderDetail = await (from order in _context.RegistrationOrder
                                         join patient in _context.Patient on order.PatientId equals patient.Id into patientGroup
                                         from patient in patientGroup.DefaultIfEmpty()
                                         join registration in _context.Registration on order.Id equals registration.RegistrationOrderId into registrationGroup
                                         from registration in registrationGroup.DefaultIfEmpty()
                                         where order.Id == orderId && !order.IsDeleted
                                         select new RegistrationOrderDetailDto
                                         {
                                             Id = order.Id,
                                             OrderNo = order.OrderNo,
                                             CreateTime = order.CreateTime,
                                             PatientId = order.PatientId,
                                             PatientName = patient.PatientName,
                                             PatientPhone = patient.Phone,
                                             PatientSex = patient.Sex,
                                             PatientAge = patient.Age,
                                             PatientAddress = patient.Address,
                                             Amount = order.Amount, // 金额
                                             OrderStatus = order.OrderStatus,
                                             OrderStatusName = order.OrderStatus.HasValue ?
                                                 GetEnumDescription(order.OrderStatus.Value) : null,
                                             // 挂号信息字段直接展开
                                             VisitTime = registration.VisitTime,
                                             Hospital = registration.Hospital,
                                             Department = registration.Department,
                                             DepartmentName = registration.Department.HasValue ?
                                                 GetEnumDescription(registration.Department.Value) : null,
                                             Doctor = registration.Doctor,
                                             DoctorTitle = registration.DoctorTitle,
                                             MedicalServiceFee = registration.MedicalServiceFee,
                                             RegistrationNo = registration.RegistrationNo
                                         }).FirstOrDefaultAsync();

                if (orderDetail == null)
                {
                    throw new InvalidOperationException($"未找到ID为{orderId}的挂号订单");
                }

                return orderDetail;
            }
            catch (Exception ex)
            {
                throw new Exception($"获取挂号订单详情时发生错误: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// 获取枚举的Description特性值
        /// </summary>
        /// <typeparam name="T">枚举类型</typeparam>
        /// <param name="enumValue">枚举值</param>
        /// <returns>Description特性值或枚举名称</returns>
        private static string GetEnumDescription<T>(T enumValue) where T : struct, Enum
        {
            var field = enumValue.GetType().GetField(enumValue.ToString());
            var attribute = field?.GetCustomAttributes(typeof(DescriptionAttribute), false).FirstOrDefault() as DescriptionAttribute;
            return attribute?.Description ?? enumValue.ToString();
        }
    }
}
